package view;

import java.awt.Dimension;
import java.awt.Font;

import javax.swing.BoxLayout;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSplitPane;

@SuppressWarnings("serial")
public class Gui extends JFrame {

	private static final String TITLE = "regsim";

	private static final Gui gui = new Gui();

	public Gui() {
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.setTitle(TITLE);
		this.buildMainWindow();
		this.pack();
		this.setVisible(true);
	}

	private void buildMainWindow() {
		this.setLayout(new BoxLayout(getContentPane(), BoxLayout.X_AXIS));
		JSplitPane splitPane1 = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
				makeInfoPanel(), makeProgramPanel());
		splitPane1.setOneTouchExpandable(true);
		JSplitPane splitPane2 = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
				splitPane1, makeSimulationPanel());
		splitPane2.setOneTouchExpandable(true);
		this.add(splitPane2);
	}

	private JComponent makeInfoPanel() {
		JSplitPane infoPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT,
				makeMacroPanel(), makeConfigPanel());
		infoPane.setOneTouchExpandable(true);
		return infoPane;
	}

	private JComponent makeMacroPanel() {
		JPanel macroPanel = new JPanel();
		macroPanel.setLayout(new BoxLayout(macroPanel, BoxLayout.Y_AXIS));
		macroPanel.setPreferredSize(new Dimension(135, 250));
		macroPanel.add(buildHeadline("Macros"));
		macroPanel.add(new MacroView());
		return macroPanel;
	}

	private JComponent makeConfigPanel() {
		JPanel configPanel = new JPanel();
		configPanel.setLayout(new BoxLayout(configPanel, BoxLayout.Y_AXIS));
		configPanel.setPreferredSize(new Dimension(135, 250));
		configPanel.add(buildHeadline("Configuration"));
		configPanel.add(new ConfigView());
		return configPanel;
	}

	private JComponent makeProgramPanel() {
		JPanel programPanel = new JPanel();
		programPanel.setLayout(new BoxLayout(programPanel, BoxLayout.Y_AXIS));
		programPanel.setPreferredSize(new Dimension(300, 500));
		programPanel.add(buildHeadline("Program"));
		programPanel.add(new CodeView());
		return programPanel;
	}

	private JComponent makeSimulationPanel() {
		JPanel simulationPanel = new JPanel();
		simulationPanel.setLayout(new BoxLayout(simulationPanel,
				BoxLayout.Y_AXIS));
		simulationPanel.setPreferredSize(new Dimension(300, 500));
		simulationPanel.add(buildHeadline("Simulation"));
		JComponent memoryView = new MemoryView();
		memoryView.setAlignmentX(LEFT_ALIGNMENT);
		JComponent accumulatorView = new AccumulatorView();
		accumulatorView.setAlignmentX(LEFT_ALIGNMENT);
		JComponent runtimeControlView = new RuntimeControlView();
		runtimeControlView.setAlignmentX(LEFT_ALIGNMENT);
		simulationPanel.add(memoryView);
		simulationPanel.add(accumulatorView);
		simulationPanel.add(runtimeControlView);
		return simulationPanel;
	}

	private JLabel buildHeadline(String name) {
		JLabel headline = new JLabel(name);
		headline.setAlignmentX(LEFT_ALIGNMENT);
		headline.setFont(new Font("Helvetica", Font.BOLD, 16));
		return headline;
	}

	public static Gui getInstance() {
		return gui;
	}
}
